<?php
	// +----------------------------------------------------------------------
	// | FileName: DrawingController.php
	// +----------------------------------------------------------------------
	// | Date: 2023/4/5 12:46:15
	// +----------------------------------------------------------------------
	// | Author: 默毅 <moyi@mymoyi.cn>
	// +----------------------------------------------------------------------
	// | Notes: 
	// +----------------------------------------------------------------------
	namespace App\Controller\Api;
	use App\Controller\AbstractController;
	use App\Model\Ai\Drawing\DrawingModel;
	use App\Model\Ai\Drawing\DrawingSampler;
	use App\Model\Ai\Drawing\DrawingServer;
	use App\Model\Ai\Drawing\DrawingTask;
	use App\Model\Ai\Drawing\DrawingVae;
	use App\Model\Ai\Drawing\Link\LinkModel;
	use App\Model\Ai\Drawing\Link\LinkVae;
	use App\Model\User;
	use App\Service\Library\CommonService;
	use App\Service\Library\DrawingService;
	use App\Service\Library\ip2regionService;
	use Hyperf\Di\Annotation\Inject;
	use Hyperf\HttpServer\Annotation\AutoController;
	use Hyperf\Redis\Redis;
	use Psr\Http\Message\ResponseInterface;
	
	#[AutoController]
	class DrawingController extends AbstractController
	{
		
		
		#[Inject]
		private DrawingService $DrawingService;

		#[Inject]
		private CommonService $CommonService;

		#[Inject]
		private ip2regionService $Ip2regionService;

		#[Inject]
		private Redis $Redis;

		public function join(): ResponseInterface
		{
			$service_id =  $this->DrawingService->joinServer($this->request->post());
			if($service_id){
				return $this->success('准备冲了！绑定显卡序列号的_你的绘图服务ID：',['service_id'=>$service_id]);
			}else{
				return $this->error('服务器加入失败，可能数据格式错了吧，～.～');
			}
		}
		
		public function add_task(){
			$ip = $this->CommonService->getRealIp();
			$btn_time = 5;
			if ($this->Redis->exists('btn:submit:' . $ip)) {
				return $this->error("急啥，接口{$btn_time}秒节流");
			}
			
			
			if ($this->Redis->exists('task_limit:' . $ip)) {
				return $this->error('30秒仅限提交1次任务');
			}
			
			$this->Redis->set('btn:submit:' . $ip, '1', $btn_time);
			
			$user_param = $this->request->post();
			
			
			
			// 可调参数
			$required_param = [
				'prompt',
				'sampler_name',
				'steps',
				'width',
				'height',
				'negative_prompt',
			];
			
			
//			zh_prompt 中文提示词 zh_negative_prompt
			
			$admin_param = [
				'batch_size' => 12,
				'save_images' => true,
			];
			
			$param = [
				'vae_hash'=> $this->request->post('vae_hash'),
				'model_hash'=>$this->request->post('model_hash'),
				'zh_prompt'=>$this->request->post('zh_prompt'),
				'zh_negative_prompt'=>$this->request->post('zh_negative_prompt')
			];
			
			
			foreach ($this->DrawingService->getLimit() as $index => $item) {
				if (in_array($index, $required_param)) {
					$value = @$admin_param[$index] ?? @$user_param[$index] ?? $item['default'] ?? null;
					if (@$item['max']) {
						if ((int)$item['max'] < (int)$value) {
							return $this->error($item['desc'] . '上限' . $item['max']);
						}
					}
					if (@$item['min']) {
						if ((int)$item['min'] > (int)$value) {
							return $this->error($item['desc'] . '下限' . $item['min']);
						}
					}
					$param[$index] = @$admin_param[$index] ?? @$user_param[$index] ?? $item['default'] ?? null;
				}
			}
			
//			return $this->error('',$param);
			
			$ips = explode('|',$this->Ip2regionService->search($ip));
			$nickname = ($ips[2]!='0'?$ips[2]:'').($ips[3]!='0'?$ips[3]:'').'的网友';
			$user_id = User::insertGetId(['nickname'=>$nickname,'avatar'=>'https://cdn.mymoyi.cn/pay/0_2_14/h5/00207-552621836.png']);
			$param['user_id'] = $user_id;
			$param['ip'] = $ip;
			$param['model_hash'] = $user_param['model_hash'];
			$param['createtime'] = time();
			$task_id = DrawingTask::insertGetId($param);
			$this->Redis->set('task_limit:' . $ip,'1',30);
			$total = DrawingTask::where('status', 'wait')->count();
			return $this->success('任务提交成功',['task_id'=>$task_id,'waits'=>$total]);
		}
		
		
		public function get_task(): ResponseInterface
		{
			$service_id = $this->request->post('service_id',2);
			$ip = $this->CommonService->getRealIp();
			print_r(['get_task',$ip]);
			if($service_id){
				$task = $this->DrawingService->getDrawingTask($service_id);
				if($task){
					$task['sd_model_checkpoint'] = LinkModel::where('hash',$task['model_hash'])->value('name');
					if($task['vae_hash']){
						$task['sd_vae'] = LinkVae::where('hash',$task['vae_hash'])->value('name');
					}
					
					// 设置服务器状态
					DrawingServer::where('id',$service_id)->update(['task_id'=>$task['id'],'usage'=>'processing']);
					
					print_r(['任务已发送',$task]);
					return $this->success('',$task);
				}else{
					return $this->success('暂无任务',[],'2',);
				}
			}else{
				return $this->error('服务器ID校验失败');
			}
		}
		
		public function get_models_list(): ResponseInterface
		{
			$list = DrawingModel::where('status' , 'normal')->orderBy('weight','desc')->get(['name','hash']);
			return $this->success('',$list->toArray());
		}
		
		
		public function get_config_list(): ResponseInterface
		{
			$model_list = DrawingModel::where('status' , 'normal')->orderBy('weight','desc')->get(['name','hash']);
			$vae_list = DrawingVae::where('status' , 'normal')->orderBy('weight','desc')->get(['name','hash']);
//			$lora_list = DrawingModel::where('status' , 'normal')->orderBy('weight','desc')->get(['name','hash']);
			$samplers_list = DrawingSampler::where('status' , 'normal')->orderBy('weight','desc')->get(['name']);
			return $this->success('',[
				'models'=>$model_list,
				'vae'=>$vae_list,
				'samplers'=>$samplers_list
			]);
		}
		public function submit_task(): ResponseInterface
		{
			if($this->request->isMethod('post')){
				$param  = $this->request->post();
				if($param){
					// 设置服务器状态
					DrawingServer::where('id',$param['service_id'])->update(['usage'=>'free']);
					
					if($this->DrawingService->pushData($param)){
						return $this->success('处理成功');
					}else{
						return $this->success('绘图数据暂存失败');
					}
				}else{
					return $this->error('序列化失败');
				}
			}
			return $this->error('Hi');
		}
	}